package cn.com.pansky.comm.interceptor;

import java.lang.reflect.Field;
import java.sql.Connection;

import javax.servlet.ServletContext;
import javax.sql.DataSource;

import net.vsame.url2sql.helper.SqlHelper;
import net.vsame.url2sql.helper.Url2SqlContext;
import net.vsame.url2sql.helper.WebHelper;
import net.vsame.url2sql.url.Interceptor;
import net.vsame.url2sql.url.impl.UrlMapping;
import net.vsame.url2sql.url.impl.UrlMapping.Chain;
import net.vsame.url2sql.utils.dataBase.OracleJdbcUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class SpringInterceptor implements Interceptor {

	private WebApplicationContext springContext;
	private DefaultListableBeanFactory beanFactory;

	@Override
	public void init(UrlMapping urlMapping, ServletContext servletContext) {
		springContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
		ConfigurableApplicationContext confiContext = (ConfigurableApplicationContext) springContext;
		beanFactory = (DefaultListableBeanFactory) confiContext.getBeanFactory();

		SqlHelper.setJdbcUtils(new OracleJdbcUtils());
		final DataSource dataSource = springContext.getBean("dataSource", DataSource.class);
		Url2SqlContext.setConnSource(new Url2SqlContext.ConnSource() {
			
			@Override
			public Connection getConnection() {
				try {
					return dataSource.getConnection();
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		});
		
	
	}

	@Override
	public void invoke(Chain chain) {
		Url2SqlContext c = WebHelper.getContext();
		
		Object action = c.getAction();
		if(action != null) {
			beanFactory.autowireBean(action);
			Field[] fields = action.getClass().getDeclaredFields();
			for (Field field : fields) {
				injectField(action, field);
			}
		}
		chain.next();
	}

	@Override
	public void destroy() {
	}

	private void injectField(Object action, Field field) {
		Autowired autowired = field.getAnnotation(Autowired.class);
		if(autowired == null) {
			return ;
		}
		
		Object bean = springContext.getBean(field.getName());
		try {
			field.setAccessible(true);
			field.set(action, bean);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

}
